package com.yint.server;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.yint.core.AbsSocketReactor;
import com.yint.core.Handler;

public class TCPSubReactor extends AbsSocketReactor implements Runnable {

	private final Selector selector;
	private boolean restart = false;
	int num;
	private ExecutorService executorService=Executors.newCachedThreadPool();

	public TCPSubReactor(Selector selector, int num) {
		this.selector = selector;
		this.num = num;
	}

	@Override
	protected void onStart() throws IOException {
		System.out.println("TCPSubReactor onStart");
	}

	public void setRestart(boolean restart) {
		this.restart = restart;
	}

	@Override
	protected void dispatch(SelectionKey selectedKey) throws IOException {
		System.out.println("TCPSubReactor dispatch");
		// 根据事件绑定的对象开新线程
		Handler handler = (Handler) selectedKey.attachment();
		if (handler != null) {
			unRegister(selectedKey, selectedKey.readyOps());
			executorService.execute(new Runnable() {
				
				@Override
				public void run() {
					try {
						handler.handle(selectedKey);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			});
		}
	}

	public void register(SocketChannel sc,int readyOps) throws IOException {
		if(getSelector()!=null) {
			// 设置为重启，暂停工作
			setRestart(true);
			// 使一个阻塞值的selector操作立即返回
			getSelector().wakeup();
			// SocketChannel向selector注册一个OP_READ事件然后返回该通道的key
			SelectionKey sk = sc.register(getSelector(), readyOps);
			sk.attach(new Process(sk, sc));
			getSelector().wakeup();
			// 重新开始工作
			setRestart(false);
		}
	}

	 protected void unRegister(SelectionKey sk, int readyOps) {
		 register(sk,sk.interestOps()& (~readyOps));
     }

	 protected void register(SelectionKey sk, int intops) {
         sk.interestOps(intops);
     }
     
	@Override
	protected Selector getSelector() {
		return selector;
	}

	@Override
	protected boolean isHandleing() {
		return !restart;
	}

	@Override
	public void run() {
		start();
	}
}